#include "utils.h"
#include <stdarg.h>
#include <sys/stat.h>

// 内存管理
void *qemu_malloc(size_t size) {
    void *ptr = malloc(size);
    if (!ptr && size > 0) {
        report_error("Failed to allocate %zu bytes", size);
        exit(1);
    }
    return ptr;
}

void *qemu_mallocz(size_t size) {
    void *ptr = qemu_malloc(size);
    memset(ptr, 0, size);
    return ptr;
}

void qemu_free(void *ptr) {
    if (ptr) {
        free(ptr);
    }
}

char *qemu_strdup(const char *str) {
    if (!str) return NULL;
    size_t len = strlen(str) + 1;
    char *new_str = (char *)qemu_malloc(len);
    memcpy(new_str, str, len);
    return new_str;
}

// 日志系统
void report_error(const char *fmt, ...) {
    va_list ap;
    fprintf(stderr, "[ERROR] ");
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    fprintf(stderr, "\n");
}

void report_info(const char *fmt, ...) {
    va_list ap;
    printf("[INFO] ");
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
    printf("\n");
}

void report_warning(const char *fmt, ...) {
    va_list ap;
    fprintf(stderr, "[WARNING] ");
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    fprintf(stderr, "\n");
}

void report_debug(const char *fmt, ...) {
#ifdef DEBUG
    va_list ap;
    printf("[DEBUG] ");
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
    printf("\n");
#endif
}

// 工具函数
int64_t round_to_cluster(int64_t value, int cluster_size) {
    return (value + cluster_size - 1) & ~(cluster_size - 1);
}

uint64_t get_file_size(const char *filename) {
    struct stat st;
    if (stat(filename, &st) == 0) {
        return st.st_size;
    }
    return 0;
}

int is_power_of_two(uint64_t x) {
    return (x != 0) && ((x & (x - 1)) == 0);
}

int file_exists(const char *filename) {
    struct stat st;
    return stat(filename, &st) == 0;
}

void hex_dump(const uint8_t *data, size_t size, uint64_t offset) {
    for (size_t i = 0; i < size; i += 16) {
        printf("%08lx: ", offset + i);

        // 十六进制显示
        for (size_t j = 0; j < 16; j++) {
            if (i + j < size) {
                printf("%02x ", data[i + j]);
            } else {
                printf("   ");
            }
            if (j == 7) printf(" ");
        }

        printf(" ");
        // ASCII 显示
        for (size_t j = 0; j < 16 && i + j < size; j++) {
            uint8_t c = data[i + j];
            printf("%c", (c >= 32 && c < 127) ? c : '.');
        }
        printf("\n");
    }
}

// 时间工具
uint64_t get_timestamp_ms(void) {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}